package com.bjpowernode.aop;

import com.bjpowernode.annotation.DataScope;
import com.bjpowernode.entity.TRole;
import com.bjpowernode.entity.TUser;
import com.bjpowernode.query.BaseQuery;
import com.bjpowernode.util.LoginInfoUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 切面类
 */
@Aspect
@Component
public class DataScopeAspect {
    /**
     * 环绕通知
     * 切入点表达式:在添加了@DataScope注解的方法上 生效
     * <p>
     * 1.获取@DataScope中的属性数据
     * 2.根据获取到的属性数据拼接sql
     *
     * @param joinPoint
     * @return
     */
    @Around("@annotation(com.bjpowernode.annotation.DataScope)") //切入点表达式
    public Object process(ProceedingJoinPoint joinPoint) throws Throwable {
        //1.获取@DataScope中的属性数据  利用反射

        //获取方法签名
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

        //获取方法上的DataScope注解对象
        DataScope dataScope = methodSignature.getMethod().getAnnotation(DataScope.class);

        //获取注解对象中的属性值
        String tableAlias = dataScope.tableAlias();//表别名
        String columnName = dataScope.columnName();//字段名


        //2.根据获取到的属性数据拼接sql
        //where tableAlias.columnName

        //判断当前登录的用户是否为管理员
        TUser tUser = LoginInfoUtil.getCurrentLoginUser();

        //获取角色信息
        List<TRole> tRoleList = tUser.getTRoleList();

        //判断角色信息中是否包含管理员
        boolean flag = tRoleList.stream().anyMatch(tRole -> "admin".equals(tRole.getRole()));

        if (!flag) {
            //当前登录的用户角色不是管理员，拼接sql语句
            Object param = joinPoint.getArgs()[0];

            if (param instanceof BaseQuery) {
                BaseQuery baseQuery = (BaseQuery) param;

                //拼接sql条件传入baseQuery对象 and u.id=2
                String sql = " and " + tableAlias + "." + columnName + "=" + tUser.getId();
                baseQuery.setFilterSQL(sql);
            }
        }

        return joinPoint.proceed();

    }
}
